package com.zzyl.intercept;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.CacheConstants;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.properties.JwtTokenProperties;
import com.zzyl.utils.JwtUtil;
import com.zzyl.utils.PathMatcherUtil;
import com.zzyl.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 管理端拦截器
 */
@Component
@RequiredArgsConstructor
public class JwtTokenInterceptor implements HandlerInterceptor {

    final JwtTokenProperties jwtTokenProperties;
    final StringRedisTemplate stringRedisTemplate;


    /**
     * 在controller方法之前执行
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //1. 获取请求头中的jwt
        String header = request.getHeader("Authorization");
        if (StrUtil.isBlank(header)) {
            throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_FAIL);
        }

        //2. 解析jwt令牌，获取用户id
        long userId;
        try {
            Claims claims = JwtUtil.parseJWT(jwtTokenProperties.getSecretKey(), header);
            String id = claims.get("id").toString();
            userId = Long.parseLong(id);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_FAIL);
        }

        //3. TODO 根据userId从redis获取url权限列表
        String redisKey = CacheConstants.USER_ACCESS_URLS + userId;
        String urlJson = stringRedisTemplate.opsForValue().get(redisKey);
        List<String> urlList = JSONUtil.toList(urlJson, String.class);
        //获取当前请求路径，拼接权限路径字符串：POST/bed/page
        String targetUrl = StrUtil.concat(true, request.getMethod(), request.getRequestURI());
        //匹配当前路径是否在urlList集合中
        boolean match = PathMatcherUtil.match(urlList, targetUrl);
        if (!match) {
            //说明权限不足，非法访问
            throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_FAIL);
        }

        //4. 将用户id存入本地线程，放行
        ThreadLocalUtil.set(userId);
        return true;
    }
}











